package org.jeecg.modules.ywSemiFinishedProductEnter.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.Assert;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import org.apache.commons.collections.CollectionUtils;
import org.jeecg.common.api.vo.Result;
import org.jeecg.constant.CommonConstant;
import org.jeecg.constant.InventoryConstant;
import org.jeecg.modules.ywSemiFinishedProductEnter.entity.YwSemiFinishedProductEnterDetail;
import org.jeecg.modules.ywSemiFinishedProductEnter.entity.YwSemiFinishedProductEnterMain;
import org.jeecg.modules.ywSemiFinishedProductEnter.mapper.YwSemiFinishedProductEnterDetailMapper;
import org.jeecg.modules.ywSemiFinishedProductEnter.mapper.YwSemiFinishedProductEnterMainMapper;
import org.jeecg.modules.ywSemiFinishedProductEnter.service.IYwSemiFinishedProductEnterDetailService;
import org.jeecg.modules.ywSemiFinishedProductEnter.service.IYwSemiFinishedProductEnterMainService;
import org.jeecg.modules.ywSemiFinishedProductInventory.entity.YwSemiFinishedProductInventoryInfo;
import org.jeecg.modules.ywSemiFinishedProductInventory.service.IYwSemiFinishedProductInventoryInfoService;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import java.io.Serializable;
import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.Collection;
import java.util.List;

/**
 * 半成品入库
 *
 * @author zk
 */
@Service
public class YwSemiFinishedProductEnterMainServiceImpl extends ServiceImpl<YwSemiFinishedProductEnterMainMapper, YwSemiFinishedProductEnterMain> implements IYwSemiFinishedProductEnterMainService {

    @Resource
    private YwSemiFinishedProductEnterMainMapper ywSemiFinishedProductEnterMainMapper;
    @Resource
    private YwSemiFinishedProductEnterDetailMapper ywSemiFinishedProductEnterDetailMapper;
    @Resource
    private IYwSemiFinishedProductEnterDetailService ywSemiFinishedProductEnterDetailService;
    @Resource
    private IYwSemiFinishedProductInventoryInfoService ywSemiFinishedProductInventoryInfoService;

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void saveMain(YwSemiFinishedProductEnterMain ywSemiFinishedProductEnterMain, List<YwSemiFinishedProductEnterDetail> ywSemiFinishedProductEnterDetailList) {
        Assert.notEmpty(ywSemiFinishedProductEnterDetailList, "入库单数据异常,请填写入库单详情！");
        ywSemiFinishedProductEnterMain.setEnterStatus(InventoryConstant.EnterStatusEnum.CREATE_END.getCode());
        ywSemiFinishedProductEnterMainMapper.insert(ywSemiFinishedProductEnterMain);

        // 保存详情
        List<YwSemiFinishedProductEnterDetail> list = new ArrayList<>();
        for (YwSemiFinishedProductEnterDetail entity : ywSemiFinishedProductEnterDetailList) {
            entity.setEnterId(ywSemiFinishedProductEnterMain.getId());
            // todo：目前填写或导入Excel时必须填写周转箱体积,如果后续要改成出入库不展示周转箱体积字段,那么需要将周转箱类型做唯一校验,通过周转箱类型查询基础信息表中的周转箱体积.
            entity.setTotalVolume(entity.getBoxVolume().multiply(new BigDecimal(entity.getBoxNum()))); // 入库体积=周转箱体积*箱子数量
            entity.setStatus(CommonConstant.StatusEnum.YES.getCode());
            list.add(entity);
        }
        ywSemiFinishedProductEnterDetailService.saveBatch(list);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public Result<?> confirmEnter(String id) {
        YwSemiFinishedProductEnterMain enterMain = this.ywSemiFinishedProductEnterMainMapper.selectById(id);
        Assert.notNull(enterMain, "入库单数据异常,请联系管理员！");
        Assert.isFalse(InventoryConstant.EnterStatusEnum.DELETE.getCode().equals(enterMain.getEnterStatus()), "入库单状态异常,请联系管理员！");
        List<YwSemiFinishedProductEnterDetail> enterDetailList = ywSemiFinishedProductEnterDetailService.selectList(id);
        Assert.notEmpty(enterDetailList, "入库单数据异常,请联系管理员！");

        long errorDataCount = enterDetailList.stream().filter(data -> data.getBoxNum() < 0).count();
        Assert.isTrue(errorDataCount == 0, "入库数量不能小于0！");

        // 封装库存信息
        for (YwSemiFinishedProductEnterDetail enterDetail : enterDetailList) {
            // 半成品库存：以入库日期、部门名称、部品号、部品名称、周转箱类型、货品位置、生产日期为唯一（箱子数量、总计收容数、入库体积存储总数）
            List<YwSemiFinishedProductInventoryInfo> list = ywSemiFinishedProductInventoryInfoService.list(new LambdaQueryWrapper<YwSemiFinishedProductInventoryInfo>()
                    .eq(YwSemiFinishedProductInventoryInfo::getEnterDate, enterMain.getEnterDate())
                    .eq(YwSemiFinishedProductInventoryInfo::getDeptName, enterDetail.getDeptName())
                    .eq(YwSemiFinishedProductInventoryInfo::getProductCode, enterDetail.getProductCode())
                    .eq(YwSemiFinishedProductInventoryInfo::getProductName, enterDetail.getProductName())
                    .eq(YwSemiFinishedProductInventoryInfo::getBoxType, enterDetail.getBoxType())
                    .eq(YwSemiFinishedProductInventoryInfo::getGoodsPosition, enterDetail.getGoodsPosition())
                    .eq(YwSemiFinishedProductInventoryInfo::getManufactureDate, enterDetail.getManufactureDate())
                    .eq(YwSemiFinishedProductInventoryInfo::getStatus, CommonConstant.StatusEnum.YES.getCode()));
            if (CollectionUtils.isNotEmpty(list)) {
                YwSemiFinishedProductInventoryInfo inventoryInfo = list.get(0);
                inventoryInfo.setBoxNum(inventoryInfo.getBoxNum() + enterDetail.getBoxNum());
                inventoryInfo.setInventoryNum(null == inventoryInfo.getInventoryNum() ? enterDetail.getTotalNum() : inventoryInfo.getInventoryNum() + enterDetail.getTotalNum());
                inventoryInfo.setInventoryVolume(null == inventoryInfo.getInventoryVolume() ? enterDetail.getTotalVolume() : inventoryInfo.getInventoryVolume().add(enterDetail.getTotalVolume()));
                ywSemiFinishedProductInventoryInfoService.updateById(inventoryInfo);
            } else {
                YwSemiFinishedProductInventoryInfo inventoryInfo = new YwSemiFinishedProductInventoryInfo();
                inventoryInfo.setEnterId(enterMain.getId());
                inventoryInfo.setEnterDate(enterMain.getEnterDate());
                inventoryInfo.setDeptName(enterDetail.getDeptName());
                inventoryInfo.setProductCode(enterDetail.getProductCode());
                inventoryInfo.setProductName(enterDetail.getProductName());
                inventoryInfo.setBoxType(enterDetail.getBoxType());
                inventoryInfo.setBoxVolume(enterDetail.getBoxVolume());
                inventoryInfo.setBoxNum(enterDetail.getBoxNum());
                inventoryInfo.setInventoryNum(enterDetail.getTotalNum());
                inventoryInfo.setInventoryVolume(enterDetail.getTotalVolume());
                inventoryInfo.setGoodsPosition(enterDetail.getGoodsPosition());
                inventoryInfo.setManufactureDate(enterDetail.getManufactureDate());
                inventoryInfo.setStatus(CommonConstant.StatusEnum.YES.getCode());
                ywSemiFinishedProductInventoryInfoService.save(inventoryInfo);
            }
        }
        // 更新主表主库状态
        enterMain.setEnterStatus(InventoryConstant.EnterStatusEnum.ENTER_END.getCode());
        this.ywSemiFinishedProductEnterMainMapper.updateById(enterMain);

        return Result.OK("入库成功！");
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void updateMain(YwSemiFinishedProductEnterMain ywSemiFinishedProductEnterMain, List<YwSemiFinishedProductEnterDetail> ywSemiFinishedProductEnterDetailList) {
        Assert.notEmpty(ywSemiFinishedProductEnterDetailList, "入库单数据异常,请填写入库单详情！");
        // 更新主库
        ywSemiFinishedProductEnterMainMapper.updateById(ywSemiFinishedProductEnterMain);

        // 删除旧数据
        ywSemiFinishedProductEnterDetailMapper.deleteByMainId(ywSemiFinishedProductEnterMain.getId());

        // 保存详情
        List<YwSemiFinishedProductEnterDetail> list = new ArrayList<>();
        for (YwSemiFinishedProductEnterDetail entity : ywSemiFinishedProductEnterDetailList) {
            entity.setId(null);
            entity.setEnterId(ywSemiFinishedProductEnterMain.getId());
            entity.setTotalVolume(entity.getBoxVolume().multiply(new BigDecimal(entity.getBoxNum()))); // 入库体积=周转箱体积*箱子数量
            entity.setCreateTime(null);
            entity.setCreateBy(null);
            entity.setStatus(CommonConstant.StatusEnum.YES.getCode());
            list.add(entity);
        }
        ywSemiFinishedProductEnterDetailService.saveBatch(list);
    }

    @Override
    @Transactional
    public void delMain(String id) {
        // 更新子表有效标志
        ywSemiFinishedProductEnterDetailMapper.deleteByMainId(id);

        // 更新主表有效标志
        YwSemiFinishedProductEnterMain ywSemiFinishedProductEnterMain = new YwSemiFinishedProductEnterMain();
        ywSemiFinishedProductEnterMain.setId(id);
        ywSemiFinishedProductEnterMain.setEnterStatus(InventoryConstant.EnterStatusEnum.DELETE.getCode());
        ywSemiFinishedProductEnterMainMapper.updateById(ywSemiFinishedProductEnterMain);
    }

    @Override
    @Transactional
    public void delBatchMain(Collection<? extends Serializable> idList) {
        for (Serializable id : idList) {
            this.delMain(id.toString());
        }
    }

}
